#ifndef MULTISET_H
#define MULTISET_H

#include "colorset.h"
#include "wfnettypes.h"

#include <coretypes.h>
#include <imultiset.h>
#include <type.h>

#include <QtCore/QHash>

namespace wfnet
{

class Multiset : public net::IMultiset, public core::Type
{
public:
    typedef QSet<ColorSet>::const_iterator ConstIterator;

private:
    typedef class QHash<ColorSet, uint>::iterator PrivateIterator;
    typedef class QHash<ColorSet, uint>::const_iterator ConstPrivateIterator;

public:
    Multiset();
    Multiset(const ColorSetName& colSetName);
    Multiset(const ColorSetName& colSetName, const TypeValue& value);
    Multiset(const Multiset& other);
    Multiset(const Multiset& other, const TypeValue& value);
    ~Multiset();

    // IMultiset
    bool isTimed() const;

    // Type
    QString name() const;
    bool matches(const TypeName& name) const;
    bool matches(const Type& type) const;
    bool canConvert(const TypeValue& value) const;
    ValueKeywordMask keywordMask() const;
    bool hasIdentity() const;
    void setIdentity(const Type& identity);

    Type* copy() const;

    TypeValue toValue() const;

    bool isEmpty() const;
    uint size() const;
    bool contains(const ColorSet& value) const;
    uint coefficient(const ColorSet& value) const;

    void insert(const ColorSet& value);
    void remove(const ColorSet& value);
    void clear();

    ColorSet at(uint index) const;

    Multiset intersect(const Multiset& other) const;

    Multiset operator+(const Multiset& other) const;
    Multiset operator-(const Multiset& other) const;
    Multiset operator*(uint scalar) const;

    bool operator<=(const Multiset& other) const;

    TypeName typeOf() const;

    ConstIterator constBegin() const;
    ConstIterator constEnd() const;

    static TypeName constructName(const ColorSetName& name);

private:
    void parseValue(const TypeValue& value);
    void fillOperations();

public:
    static const TypeName NAME;
    static const ValueKeywordMask KEYWORD_MASK;

private:
    TypeName m_colSetName;
    QHash<ColorSet, uint> m_values;
    TypeName m_name;
};

} // namespace wfnet

#endif
